// https://www.lintcode.com/problem/update-bits/description

class Solution {
public:
    /**
     * @param n: An integer
     * @param m: An integer
     * @param i: A bit position
     * @param j: A bit position
     * @return: An integer
     */
     
    // 右移操作分为算数右移和逻辑右移
    // 算术右移是带符号的右移，逻辑右移是不带符号的右移。
    // C/C++语言中逻辑右移和算数右移共享同一个运算符
    // >>。编译器决定使用逻辑右移还是算数右移，根据的是运算数的类型。如果运算数类型是unsign
    // ed则采用逻辑右移，而signed则采用算数右移。对于signed类型的数据，如果需要使用算数右移
    // ，或者unsigned类型的数据需要使用逻辑右移，都需要进行类型转换。

    int updateBits(int n, int m, int i, int j) {
        // 注意右移：逻辑右移；32-j-i位
        int mask = ~((-1 << i) & ((unsigned)-1 >> (32 - j - 1)));
        return n & mask | (m << i);
    }
};